import generate from '@/utils/generate'

let bodyTheme = ''
const root = new Map()

/**
 * 改变主题
 * @param theme {String} 主题的名字
 */
export function changeTheme(theme) {
  if (document.body.classList.contains(bodyTheme)) {
    document.body.classList.remove(bodyTheme)
  }
  if (theme) {
    bodyTheme = `theme-${theme}`
    document.body.classList.add(bodyTheme)
  }
}

export function changeCompactTable(value) {
  if (value) {
    document.body.classList.add('compact-table')
  } else {
    document.body.classList.remove('compact-table')
  }
}

const cssUpdate = cssUpdateList()

function cssUpdateList() {
  let syncChangeCount = 0
  let setIntervalId = null
  let themeName = null
  const add = (theme) => {
    if (syncChangeCount === 0) {
      let oldChangeCount = syncChangeCount
      setIntervalId = setInterval(() => {
        if (oldChangeCount === syncChangeCount) {
          clearInterval(setIntervalId)
          update(themeName)
        } else {
          oldChangeCount = syncChangeCount
        }
      }, 100)
    }
    themeName = theme
    syncChangeCount++
  }
  const update = (themeName) => {
    const id = 'theme-var'
    const clazz = themeName !== 'default' ? `.theme-${themeName}` : ':root'
    let style = document.getElementById(id)
    if (style) {
      document.head.removeChild(style)
    }
    style = document.createElement('style')
    style.id = id
    style.setAttribute('type', 'text/css')
    style.innerHTML = `${clazz} { ${Array.from(root.keys()).map(i => {
      return `--${i}:${root.get(i)}`
    }).join(';')}`
    document.head.appendChild(style)
    syncChangeCount = 0
  }
  return {
    add,
    update
  }
}

/**
 * 改变CSS变量
 * @param key {String} 变量名(不需要加--前缀)
 * @param value {Number|String} 值
 * @param theme {String} 主题
 */
export function changeCssVariable(key, value, theme) {
  if (value === undefined) return
  if (key) {
    if (value === null && root.has(key)) {
      root.delete(key)
    } else if (value !== null) {
      root.set(key, value)
    }
  }
  cssUpdate.add(theme)
}

export function changeColor(color, dark, darkClass = 'theme-dark') {
  const id = `theme-dark-var`
  const elem = document.getElementById(id)
  if (elem == null ? void 0 : elem.parentNode) {
    elem.parentNode.removeChild(elem)
  }
  if (color) {
    const colors = generate(color, dark === 'dark' ? { theme: 'dark' } : {})
    const clazz = dark === 'dark' ? `.${darkClass}` : ':root'
    const elem2 = document.createElement('style')
    elem2.id = id
    elem2.setAttribute('type', 'text/css')
    elem2.innerHTML = `${clazz}{` + colors.map((c, i) => {
      return `--color-primary-${i + 1}:${c};`
    }).concat([`--color-primary:${color};`]).join('') + '}'
    document.head.appendChild(elem2)
    document.body.dataset.theme = color
  } else {
    document.body.removeAttribute('data-theme')
  }
  if (dark === 'dark') {
    document.body.classList.add(darkClass)
  } else {
    document.body.classList.remove(darkClass)
  }
}

/**
 *
 * @param routes {Array} 遍历的路由
 * @param routePath {String|Number} ID | 路径 | 名称
 * @param option {String} menuId | path | name
 * @return {Array} 路由的路径数组
 */
export function resolveRoute(routes, routePath, option = 'menuId') {
  const path = []
  const findRoutes = (arr, target) => {
    for (let i = 0; i < arr.length; i++) {
      let condition = arr[i][option]
      if (option === 'menuId') {
        condition = (arr[i].meta && arr[i].meta[option]) || null
      }
      if (condition === target) {
        path.push(arr[i])
        return true
      } else if (arr[i].children) {
        const result = findRoutes(arr[i].children, target)
        if (result) {
          path.unshift(arr[i])
          return true
        }
      }
    }
    return null
  }
  findRoutes(routes, routePath)
  return path
}

/**
 * 合并并规范路径
 * @param paths {Object} Route | 类似 Route 的对象
 * @return {String}
 */
export function resolvePath(paths) {
  let fullPath = formatPath(paths.map(i => i.path).join('/'))
  if (paths && fullPath.length) {
    const query = paths[paths.length - 1].query
    const params = []
    if (query) {
      for (const key of Object.keys(query)) {
        params.push(key + '=' + query[key])
      }
    }
    if (params.length) {
      fullPath += '?' + params.join('&')
    }
  }
  return fullPath
}

/**
 * 合并并规范路径
 * @param path {String} 路径
 * @return {String}
 */
export function formatPath(path) {
  return path.replaceAll(/\/+/g, '/')
}

